<?php

/**
 * Created by PhpStorm.
 * User: simon
 * Date: 2017/2/11
 * Time: 11:00
 */
class IpSequenceChecker extends BaseSafeChecker
{
    private $actionName = null;
    private $intervalSeconds = 60;
    private $maxActions = 600;

    public function check()
    {
        global $_SERVER;
        $ip = RequestUtils::get_remote_addr();
        if ($this->ipBlocked()) {
            $this->debug("$ip is in black list");
            return false;
        }
        if ($this->ipOpened()) {
            $this->debug("$ip is in white list");
            return true;
        }
        $list = $this->getRecentActions();
        $size = count($list);
        $name = $this->getActionName();
        $this->debug("$ip $name , " . $this->getIntervalSeconds() . "秒钟内访问 $size 次 超出限制频率");
        if ($size >= $this->getMaxActions()) {
            $this->debug("$ip 超出限制频率");
            $this->blockIp($ip);
            return false;
        }
        MemcacheUtils::cache($this->getCacheKey(), $list, false, $this->getIntervalSeconds() + 10);
        return true;
    }

    public function getRecentActions()
    {
        $key = $this->getCacheKey();
        $list = MemcacheUtils::get($key, []);
        $result = [];
        if (!empty($list)) {
            $compare = time() - $this->getIntervalSeconds();
            foreach ($list as $time) {
                if ($time >= $compare) {
                    array_push($result, $time);
                }
            }
        }
        array_push($result, time());
        return $result;
    }


    public function getCacheKey()
    {
        $ip = RequestUtils::get_remote_addr();
        return "cached:" . $ip . ":" . $this->getActionName();
    }

    /**
     * @return null
     */
    public function getActionName()
    {
        return $this->actionName;
    }

    /**
     * @param null $actionName
     */
    public function setActionName($actionName)
    {
        $this->actionName = $actionName;
    }

    /**
     * @return int
     */
    public function getIntervalSeconds()
    {
        return $this->intervalSeconds;
    }

    /**
     * @param int $intervalSeconds
     */
    public function setIntervalSeconds($intervalSeconds)
    {
        $this->intervalSeconds = $intervalSeconds;
    }

    /**
     * @return int
     */
    public function getMaxActions()
    {
        return $this->maxActions;
    }

    /**
     * @param int $maxActions
     */
    public function setMaxActions($maxActions)
    {
        $this->maxActions = $maxActions;
    }


}